/*
 * GerenteMergeSort.c
 *
 *  Created on: 13/07/2011
 *      Author: Hyzandey
 */

#include "GerenteMergeSort.h"

int geraHeap(int quantidadeRegistros, char **listaRegistros,
		RegistroDiarioNode **heap) {
	int i = 0;
	for (i = 0; i < quantidadeRegistros; i++) {

		char *cabecalho = strstr(listaRegistros[i], "Transacao");

		if (cabecalho) {
			continue;
		}

		char **listaCampos = NULL;

		int quantidadeCampos = tokenizaString(listaRegistros[i], "|",
				&listaCampos);

		if (!quantidadeCampos || quantidadeCampos != 3) {
			return EXIT_FAILURE;
		}

		RegistroDiario *registroDiario = criaRegistroDiario(listaCampos[0],
				listaCampos[1], listaCampos[2]);

		if (!registroDiario) {
			return EXIT_FAILURE;
		}

		insereRegistroDiario(heap, registroDiario);

	}

	return EXIT_SUCCESS;
}

int geraRuns(const int numeroRuns, FILE **listaRuns) {

	FILE *fpLivroDiario = abreArquivoLeitura("livrodiario.txt");

	if (!fpLivroDiario) {
		return EXIT_FAILURE;
	}

	int tamanhoArquivo = medeTamanhoArquivo(fpLivroDiario);

	if (tamanhoArquivo == ERRO_TAMANHO_ARQUIVO) {
		return EXIT_FAILURE;
	}

	int tamanhoRun = tamanhoArquivo / numeroRuns;

	int offsetArquivo = 0;

	int i = 0;

	for (i = 0; i < numeroRuns + 1; i++) {
		char *arquivoFonteBuffer = recuperaBufferArquivo(fpLivroDiario,
				offsetArquivo, tamanhoRun);

		if (!arquivoFonteBuffer) {
			liberaPonteiro(arquivoFonteBuffer);

			return EXIT_FAILURE;
		}

		char **listaRegistros = NULL;

		int quantidadeRegistros = tokenizaString(arquivoFonteBuffer, "\n",
				&listaRegistros);

		if (!quantidadeRegistros) {
			liberaPonteiro(arquivoFonteBuffer);

			return EXIT_FAILURE;
		}

		RegistroDiarioNode *heap = NULL;

		int sucesso = geraHeap(quantidadeRegistros, listaRegistros, &heap);

		if (sucesso == EXIT_FAILURE) {
			limpaArvore(heap);
			liberaPonteiro(arquivoFonteBuffer);

			return EXIT_FAILURE;
		}

		char *runBuffer = (char *) calloc(tamanhoRun, sizeof(char));

		int posicaoRunBuffer = 0;

		while (heap) {
			RegistroDiario *menor = retiraMenorRegistroDiario(&heap);

			if (!menor) {
				limpaArvore(heap);
				liberaPonteiro(arquivoFonteBuffer);

				return EXIT_FAILURE;
			}

			liberaPonteiro(menor);
		}

		limpaArvore(heap);

		liberaPonteiro(arquivoFonteBuffer);
	}

	return EXIT_SUCCESS;
}

int processaDados(int numeroRuns) {

	FILE **listaRuns = (FILE **) malloc(sizeof(FILE *) * numeroRuns + 1);

	if (!(listaRuns)) {
		return EXIT_FAILURE;
	}

	int sucesso = geraRuns(numeroRuns, listaRuns);

	if (!sucesso) {
		liberaArquivos(listaRuns, numeroRuns + 1);
		free(listaRuns);

		return EXIT_SUCCESS;
	}

	liberaArquivos(listaRuns, numeroRuns + 1);
	free(listaRuns);

	return EXIT_SUCCESS;
}

